package com.notebad.ui;

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.notebad.R;

/**
 * 
 * @author Mat
 * Records and plays sounds
 */
public class AudioPlayerView extends Activity implements OnClickListener, OnCompletionListener {

	private static final String TAG = "[AudioPlayerView]";
	private ImageButton stopButton;
	private ImageButton playButton;
	private ImageButton pauseButton;
	private TextView timer;
	private ProgressBar progressBar;
	private updateThread thread;

	private MediaPlayer player;
	
	private String path;
	

	Handler handler = new Handler()
	{
		public void handleMessage(Message msg) 
		{
			progressBar.setProgress(player.getCurrentPosition()+20);
			timer.setText(convertTime(player.getCurrentPosition()+20) + " / " + convertTime(player.getDuration()));
		}
	};

	@Override
	public void onClick(View view) 
	{
		switch(view.getId()) 
		{
		case R.id.Stop:
			Log.d(TAG, "Stop");
			try 
			{
				this.stop();
			} 
			catch (IllegalStateException e1) 
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} 
			catch (IOException e1) 
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			return;

		case R.id.Play:
			Log.d(TAG, "Play");
			try 
			{
				this.play();
			} 
			catch (IllegalArgumentException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			catch (IOException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return;

		case R.id.Pause:
			Log.d(TAG, "Pause");
			this.pause();
			return;
		}
	}
	
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		Log.d(TAG, "onCreate");

		setContentView(R.layout.audio_player);		
		
		stopButton = (ImageButton) findViewById(R.id.Stop);
		stopButton.setOnClickListener(this);
		stopButton.setEnabled(false);
		
		playButton = (ImageButton) findViewById(R.id.Play);
		playButton.setOnClickListener(this);
		
		pauseButton = (ImageButton) findViewById(R.id.Pause);
		pauseButton.setOnClickListener(this);
		pauseButton.setEnabled(false);
		pauseButton.setVisibility(View.GONE);
		
		timer = (TextView) findViewById(R.id.Time);
		
		progressBar = (ProgressBar) findViewById(R.id.ProgressBar);
		
		// Get the path of the selected sound file
		Bundle param = this.getIntent().getExtras();
	    if(param != null)
	    {
	    	path = param.getString("soundPath"); 
	    }
	}
	
	protected void onDestroy() 
	{
		Log.d(TAG, "onDestroy");

		if (player != null) 
		{
			player.release();
		}
		if(thread != null)
		{
			thread.stop();
		}
		Intent intent = new Intent(this, VisualisationView.class);
		intent.putExtra("tab", 2);
		startActivity(intent);
		super.onDestroy();
	}

	private void pause()
	{
		if (player != null && player.isPlaying()) 
		{
			player.pause();
			
			stopButton.setEnabled(true);
			switchButtons();
		}
	}

	private void play() throws IllegalArgumentException, IOException
	{
		/*
		 * If the player already exists
		 */
		if (player != null) 
		{
			Log.d(TAG, "Player already exists");
			player.start();
			progressBar.setMax(player.getDuration());
			thread.start();
			stopButton.setEnabled(true);
			switchButtons();
		}
		else
		{
			/*
			 * Test if the file exists before launching the player
			 */
			File file = new File(path);
			if(file.exists())
			{
				Log.d(TAG, "Creation of player");
				player = new MediaPlayer();
				player.setOnCompletionListener(this);
				player.setDataSource(path);
				player.prepare();
				player.start();
				
				progressBar.setMax(player.getDuration());
				thread = new updateThread();
				thread.start();
				stopButton.setEnabled(true);
				switchButtons();
			}
			else
			{
				Log.d(TAG, "File : "+path+" does not exist");
			}
		}
	}
	
	/**
	 * Stops the player.
	 * @throws IOException 
	 * @throws IllegalStateException 
	 */
	private void stop() throws IllegalStateException, IOException
	{
		if(player != null)
		{			
			thread.stop();
			
			/*
			 * pauseButton activated
			 */
			if(player.isPlaying())
			{
				Log.d(TAG, "isPlaying");
				stopButton.setEnabled(false);
				switchButtons();
			}
			else
			{
				Log.d(TAG, "!isPlaying");
				stopButton.setEnabled(false);
			}
			
			player.stop();
			progressBar.setProgress(0);
			timer.setText(convertTime(0) + " / " + convertTime(player.getDuration()));
			player.release();
			player = null;
		}
	}
	
	private String convertTime(int time)
	{
	    String format = String.format("%%0%dd", 2);  
	    time = time / 1000;  
	    String seconds = String.format(format, time % 60);  
	    String minutes = String.format(format, (time % 3600) / 60);  
	    String hours = String.format(format, time / 3600);
	    
	    String result = "";
	    if(hours.compareTo("00") == 0)
	    {
	    	result = minutes + ":" + seconds;
	    }
	    else
	    {
	    	result =  hours + ":" + minutes + ":" + seconds; 
	    }
	    return result; 
	}
	
	private class updateThread implements Runnable {
		
		private volatile Thread blinker;

		public void start() 
		{
	        blinker = new Thread(this);
	        blinker.start();
	    }
		
		public void stop() 
		{
			blinker = null;
		}

		public void run() 
		{
			Thread thisThread = Thread.currentThread();
			while (blinker == thisThread && player.getCurrentPosition()+20<player.getDuration()) 
			{
				try
				{
					Log.d(TAG, "Current : "+player.getCurrentPosition());
					Log.d(TAG, "Duration : "+player.getDuration());
					handler.sendMessage(handler.obtainMessage());
					Thread.sleep(1000);
				}
				catch(InterruptedException e)
				{
					Log.d(TAG, "Thread updateView interrupted");
				}
			}
	    }
	}

	public void onCompletion(MediaPlayer mp) 
	{
		Log.d(TAG, "onCompletion called");
		
		timer.setText(convertTime(mp.getDuration()) + " / " + convertTime(mp.getDuration()));
		progressBar.setProgress(mp.getDuration());
    	
		stopButton.setEnabled(false);
		switchButtons();
	}
	
	private void switchButtons()
	{
		if(playButton.isEnabled())
		{
			pauseButton.setEnabled(true);
			playButton.setEnabled(false);
			pauseButton.setVisibility(View.VISIBLE);
			playButton.setVisibility(View.GONE);
		}
		else
		{
			pauseButton.setEnabled(false);
			playButton.setEnabled(true);
			pauseButton.setVisibility(View.GONE);
			playButton.setVisibility(View.VISIBLE);
		}
	}
}
